//! @author Adam Emil Skoog
//! @date   2012-01-05

#ifndef MEHDI_LEVEL_H_
	#define MEHDI_LEVEL_H_
	#include "Object.h"
	#include "Body.h"
	#include "kedja/Component.h"
	#include <vector>

	namespace mehdi
	 {
		class Mehdi;

		class Level
		 {
			public:
				Level();
				template<class T> T *const createObject();
				template<class T> bool destroyObject(T *const);
				template<class T> bool destroyObjectAt(const unsigned &);
				void update();
				void copyMehdi(Mehdi *const,Level *const);
				void eraseMehdi();
				Level &setCameraMovementEnabled(const bool &enable = true);
				const bool &cameraMovementIsEnabled() const;
				~Level();

			private:
				std::vector<Object *> objects;
				std::vector<Body *>   bodies;
				bool                  cameraMovementEnabled;

			friend class Body;
		 };

		template<class T> T *const Level::createObject()
		 {
			T *const result(new T);
			objects.push_back(result);
			return result;
		 }

		template<class T> bool Level::destroyObject(T *const object)
		 {
			for (unsigned i(0); i < objects.size(); ++ i)
			 {
				if (objects[i] == object)
				 {
					if (dynamic_cast<Body *>(object))
						for (unsigned j(0); j < bodies.size(); ++ j)
							if (bodies[j] == object)
								bodies.erase(bodies.begin() + j);

					delete object;
					objects.erase(objects.begin() + i);
					return true;
				 }
			 }

			return false;
		 }

		template<class T> bool Level::destroyObjectAt(const unsigned &index)
		 {
			if (static_cast<int>(index) < static_cast<int>(objects.size()))
			 {
				if (dynamic_cast<Body *>(objects[index]))
					for (unsigned i(0); i < bodies.size(); ++ i)
						if (bodies[i] == objects[index])
							bodies.erase(bodies.begin() + i);

				delete objects[index];
				objects.erase(objects.begin() + index);
				return true;
			 }

			return false;
		 }
	 }
#endif
